package com.naiterui.ehp.bs.recommend.service.impl;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.esign.PreSignResultBO;
import com.naiterui.ehp.bp.bo.esign.RecomSignParamBO;
import com.naiterui.ehp.bp.bo.recommend.param.RecomAuditParamBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.biz.AppJumpProtocol;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bp.utils.notice.AppPushUtil;
import com.naiterui.ehp.bp.utils.sms.SMSUtil;
import com.naiterui.ehp.bp.utils.sms.SMSUtil.Template;
import com.naiterui.ehp.bs.recommend.bean.DrMedicationRecomInfo;
import com.naiterui.ehp.bs.recommend.bean.MedicationRecom;
import com.naiterui.ehp.bs.recommend.bean.RecomAuditConfig;
import com.naiterui.ehp.bs.recommend.bean.RecomAuditLog;
import com.naiterui.ehp.bs.recommend.bean.RecomAuditOperationLog;
import com.naiterui.ehp.bs.recommend.bean.RecomEsignPharmacist;
import com.naiterui.ehp.bs.recommend.bean.RecomPrescription;
import com.naiterui.ehp.bs.recommend.bean.SysAdminInfo;
import com.naiterui.ehp.bs.recommend.exception.ExceptionCodes;
import com.naiterui.ehp.bs.recommend.func.RecomSettingFunc;
import com.naiterui.ehp.bs.recommend.remote.IEsignFeignClient;
import com.naiterui.ehp.bs.recommend.remote.IPharmacistFeignClient;
import com.naiterui.ehp.bs.recommend.remote.IRecommendRemoter;
import com.naiterui.ehp.bs.recommend.repository.mysql.IConsultSessionRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IMedicationRecomInfoRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IMedicationRecomRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IRecomAuditConfigRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IRecomAuditLogRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IRecomEsignPharmacistRepository;
import com.naiterui.ehp.bs.recommend.service.IESignService;
import com.naiterui.ehp.bs.recommend.service.IRecomAuditOperationLogService;
import com.naiterui.ehp.bs.recommend.service.IRecomAuditService;
import com.naiterui.ehp.bs.recommend.service.IRecomCreaterService;
import com.naiterui.ehp.bs.recommend.service.IRecomService;
import com.naiterui.ehp.bs.recommend.service.ISysAdminInfoService;
import com.naiterui.ehp.bs.recommend.vo.PharmacistVO;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @author guoyongxiang
 * @date 2019-06-20 15:00
 * @since 1.0.0
 */
@Service
public class RecomAuditServiceImpl implements IRecomAuditService {

    private static final Logger LOGGER = LoggerFactory.getLogger(RecomAuditServiceImpl.class);

    private static final Integer RECOM_AUDIT_TIMEOUT_MINUTE = ConfigUtil.getInt("recom.audit.timeout");

    /**
     * 药师审核处方锁键前缀
     */
    public static final String RECOM_PHARMACIST_AUDIT_LOCK_KEY = CommonConstant.REDIS_PRE_PHARMACIST + "recom_audit_";

    public static String PUSH_MSG_ASSIGN = "您有新的待审核处方，编号：%s，请及时处理。";
    public static String PUSH_MSG_REASSIGN = "由于您长时间未进行审核，编号：%s，已被重新分配。";

    /**
     * 处方审核汇总通知短信
     */
    public static String SMS_PENDING_SUMMARY = "平台有%s个处方仍未审核，可登录后台查看，请及时与相关药师进行沟通。";
    public static String SMS_PENDING_NO = "平台当前无待审核处方，请知悉。";

    /**
     * 处方审核不通过push
     */
    public static String PUSH_MSG_RECOM_AUDIT_NOT_PASS = "您有一个处方审核不通过";
    public static int RECOM_DEFAULT_DATA_NUM = 0;

    @Autowired
    private IRecomAuditConfigRepository recomAuditConfigRepository;
    @Autowired
    private IRecomAuditLogRepository recomAuditLogRepository;
    @Autowired
    private IRecomService recomService;
    @Autowired
    private IRecomEsignPharmacistRepository recomEsignPharmacistRepository;
    @Autowired
    private IMedicationRecomInfoRepository medicationRecomInfoRepository;
    @Autowired
    private IMedicationRecomRepository medicationRecomRepository;
    @Autowired
    private RecomSettingFunc recomSettingFunc;
    @Autowired
    private IRecomAuditOperationLogService recomAuditOperationLogService;
    @Autowired
    private IPharmacistFeignClient pharmacistFeignClient;
    @Autowired
    private IEsignFeignClient esignFeignClient;
    @Autowired
    private IRecomCreaterService recomCreaterService;
    @Autowired
    private IRecommendRemoter remoter;
    @Autowired
    private ISysAdminInfoService sysAdminInfoService;
    @Autowired
    private IESignService esignService;

    @Autowired
    private Executor taskExecutor;

    @Autowired
    private IConsultSessionRepository consultSessionRepository;

    @Override
    public PreSignResultBO preSignPh(Long recomId, Long pharmacistId) throws BusinessException {
        // 查询处方是否签名
        DrMedicationRecomInfo recomInfo = medicationRecomInfoRepository.findFirstByRecommendId(recomId);
        MedicationRecom recom = medicationRecomRepository.get(recomId);
        if (recomInfo == null || recom == null) {
            LOGGER.warn("药师签名-处方数据缺失 recomId:{}", recomId);
            throw new BusinessException(ExceptionCodes.RECOM_NOT_FOUND);
        }

        if (recomInfo.getDoctorSignStatus() != DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_DONE) {
            LOGGER.info("药师签名-处方医师未进行电子签名,药师跳过电子签名 recomId:{}", recomId);
            throw new BusinessException(ExceptionCodes.ESIGN_PRESCRIPTION_FILE_NOT_FOUND, "医师电子签名文件不存在，无法进行电子签名");
        }
        // 查询医师签名pdf文件
        String pdfPath = this.getDoctorSignFile(recomId);
        RecomSignParamBO preSignVO = RecomSignParamBO.builder()
                                                     .signUserId(pharmacistId)
                                                     .bizSn(recom.getSerialNumber())
                                                     .pdfPath(pdfPath)
                                                     .createdAt(recom.getCreatedAt())
                                                     .patientName(recomInfo.getPatientName())
                                                     .patientGender(recomInfo.getPatientGender())
                                                     .patientAge(recomInfo.getPatientAge() + recomInfo.getPatientAgeUnit())
                                                     .requestFrom(RecomSignParamBO.REQUEST_FROM_CMS)
                                                     .build();
        return esignFeignClient.preSignPh(preSignVO);
    }

    @Override
    public void pharmacistSign(RecomAuditParamBO auditParamBO, String operator) throws BusinessException {
        // 查询药师用户
        RecomEsignPharmacist user = recomEsignPharmacistRepository
                .findFirstByPharmacistIdAndStatus(auditParamBO.getPharmacistId(),
                                                  RecomEsignPharmacist.STATUS_NORMAL);
        if (user == null) {
            LOGGER.warn("药师信息未同步 pharmacistId:{}, recomId:{}, status:{}, remark:{}", auditParamBO.getPharmacistId(),
                        auditParamBO.getRecomId(),
                        auditParamBO.getStatus(),
                        auditParamBO.getRemark());
            throw new BusinessException(ExceptionCodes.PHARMACIST_INFO_NOT_SYNC);
        }
        this.pharmacistSign(auditParamBO.getRecomId(), auditParamBO.getUniqueId(), user, auditParamBO.getSignPwd());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void audit(RecomAuditParamBO auditParamBO, String operator) throws BusinessException {

        RecomAuditLog auditLog = recomAuditLogRepository.findFirstByRecomId(auditParamBO.getRecomId());
        if (auditLog == null) {
            LOGGER.warn("处方不存在 recomId:{}", auditParamBO.getRecomId());
            throw new BusinessException(ExceptionCodes.PARAM_ERROR);
        }
        if (auditLog.getStatus() != RecomAuditLog.AUDIT_STATUS_PENDING) {
            LOGGER.warn("处方已审核 recomId:{}, status:{}", auditParamBO.getRecomId(), auditLog.getStatus());
            throw new BusinessException(ExceptionCodes.RECOM_CMS_AUDIT_ALREADY);
        }

        // 查询药师用户
        Long pharmacistId = auditParamBO.getPharmacistId();
        RecomEsignPharmacist user = recomEsignPharmacistRepository
                .findFirstByPharmacistIdAndStatus(pharmacistId,
                                                  RecomEsignPharmacist.STATUS_NORMAL);
        if (user == null) {
            LOGGER.warn("药师信息未同步 pharmacistId:{}, recomId:{}, status:{}, remark:{}", pharmacistId,
                        auditParamBO.getRecomId(),
                        auditParamBO.getStatus(),
                        auditParamBO.getRemark());
            throw new BusinessException(ExceptionCodes.PHARMACIST_INFO_NOT_SYNC);
        }

        MedicationRecom recom = medicationRecomRepository.get(auditParamBO.getRecomId());
        if (recom == null) {
            LOGGER.warn("处方无效，处方ID不存在，recomId:{}", auditParamBO.getRecomId());
            throw new BusinessException(ExceptionCodes.RECOM_NOT_FOUND);
        }

        if (recom.getExpireAt().getTime() < System.currentTimeMillis()) {
            LOGGER.warn("处方已过期，recomId:{}", auditParamBO.getRecomId());
            throw new BusinessException(ExceptionCodes.ILLEGAL_REQUEST, "处方已超时效，不可审核");
        }

        // 审核权限校验
        if (!auditLog.getStatus().equals(RecomAuditLog.AUDIT_STATUS_PENDING)) {
            LOGGER.warn("处方已审核 recomId:{}, preAuditStatus:{}", auditParamBO.getRecomId(), auditLog.getPreAuditStatus());
            throw new BusinessException(ExceptionCodes.RECOM_CMS_AUDIT_ALREADY);
        }
        Date auditTime = new Date();

        auditLog.setStatus(auditParamBO.getStatus());
        auditLog.setPharmacistId(user.getPharmacistId());
        auditLog.setPharmacistName(user.getName());
        auditLog.setStatus(auditParamBO.getStatus());

        auditLog.setPreAuditStatus(auditParamBO.getStatus());
        auditLog.setPrePharmacistId(user.getPharmacistId());
        auditLog.setPrePharmacistName(user.getName());
        auditLog.setPreAuditTime(auditTime);

        auditLog.setRemark(auditParamBO.getRemark());
        auditLog.setPharmacistId(user.getPharmacistId());
        auditLog.setPharmacistName(user.getName());
        auditLog.setChangedAt(auditTime);
        auditLog.setChangedBy(operator);
        recomAuditLogRepository.update(auditLog);

        // 审核结果通知
        if (RecomAuditLog.AUDIT_STATUS_PASS == auditParamBO.getStatus()) {
            // 药师签名
            if (auditParamBO.getForce() == null || auditParamBO.getForce() != RecomAuditParamBO.FORCE_TRUE) {
                // TODO 校验电子签名状态 （由于签名结果回调有延迟，暂时取消校验）
                //DrMedicationRecomInfo info = medicationRecomInfoDao.getRecomInfoByRecomId(auditParamBO.getRecomId());
                //if(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_DONE != info.getPharmacistSignStatus()){
                //    LOGGER.warn("处方审核-未收到药师签名结果 recomId:{}", info.getRecommendId());
                //    throw new BusinessException(ExceptionCodes.ESIGN_GET_SIGN_RESULT_FIALED, "暂未查询到药师签名结果，请稍后再试");
                //}
                //                pharmacistSign(auditParamBO.getRecomId(), user, auditParamBO.getSignPwd());
            } else {
                LOGGER.info("处方审核-接收到强制审核标识，该处方跳过药师电子签名 recomId:{}, status:{}, operator:{}", auditParamBO.getRecomId(),
                            auditParamBO.getStatus(),
                            operator);
            }

            recomService
                    .saveCrmRecomConfirm(auditParamBO.getRecomId(), user.getPharmacistId(), user.getName(), auditTime.getTime(),
                                         DrMedicationRecomInfo.CHECKING_STATUS_PASS,
                                         auditParamBO.getRemark());
            // 保存操作日志
            recomAuditOperationLogService.addLog(recom.getId(), user.getName(), RecomAuditOperationLog.TYPE_PASS);
        } else {
            // 不通过
            recomService
                    .saveCrmRecomConfirm(auditParamBO.getRecomId(), user.getPharmacistId(), user.getName(), auditTime.getTime(),
                                         DrMedicationRecomInfo.CHECKING_STATUS_NOT_PASS,
                                         auditParamBO.getRemark());
            // 保存操作日志
            recomAuditOperationLogService
                    .addLog(recom.getId(), user.getName(), RecomAuditOperationLog.TYPE_NO_PASS, auditParamBO.getRemark());
            //处方审核不通过发送异步push消息
            taskExecutor.execute(() -> {
                pushRecomMsg(recom);
            });
        }
    }

    /**
     * 处方审核不通过：发送处方push消息
     */
    private void pushRecomMsg(MedicationRecom recom) {
        try {
            //默认聊天详情页
            AppJumpProtocol protocol = null;
            String params = StrUtil.EMPTY;
            if (null != recom.getSessionId() && RECOM_DEFAULT_DATA_NUM != recom.getSessionId()) {
                // 判断是否是图文问诊，跳转到聊天框
                protocol = AppJumpProtocol.DR_CHATDETAIL;
                params = consultSessionRepository.get(recom.getSessionId()).getSessionId();
            } else {
                // 视频问诊和续方来源，跳转到失效处方列表
                protocol = AppJumpProtocol.DR_INVALID_RECOM;
            }
            //查询video_consult_message找到处方消息判断是否是视频问诊
            AppPushUtil.sendDrPush(ConfigUtil.getString("push.message.server"), recom.getDoctorId(), PUSH_MSG_RECOM_AUDIT_NOT_PASS, protocol, params);
        } catch (Exception e) {
            LOGGER.error("发送处方审核不通过PUSH异常 recom:{}", recom.getId(), e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void auditConfig(Integer auditType, String remark, String operator) {
        RecomAuditConfig config = new RecomAuditConfig();
        config.setAuditType(auditType);
        config.setRemark(remark);
        config.setCreatedAt(new Date());
        config.setCreatedBy(operator);
        recomAuditConfigRepository.save(config);

        // 刷新缓存
        recomSettingFunc.refreshSetting();
    }

    /**
     * 药师签名
     *
     * @param recomId
     * @param user
     * @param signPwd
     * @throws BusinessException
     */
    @Override
    public void pharmacistSign(Long recomId, String uniqueId, RecomEsignPharmacist user, String signPwd) throws BusinessException {

        // 查询处方是否签名
        DrMedicationRecomInfo recomInfo = medicationRecomInfoRepository.findFirstByRecommendId(recomId);
        MedicationRecom recom = medicationRecomRepository.get(recomId);
        if (recomInfo == null || recom == null) {
            LOGGER.warn("药师签名-处方数据缺失 recomId:{}", recomId);
            throw new BusinessException(ExceptionCodes.RECOM_NOT_FOUND);
        }

        if (recomInfo.getDoctorSignStatus() != DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_DONE) {
            LOGGER.info("药师签名-处方医师未进行电子签名,药师跳过电子签名 recomId:{}", recomId);
            return;
        }
        // 查询医师签名pdf文件
        String pdfPath = this.getDoctorSignFile(recomId);
        // 药师签署
        RecomSignParamBO recomPreSignVO = RecomSignParamBO.builder()
                                                          .signUserId(user.getPharmacistId())
                                                          .pdfPath(pdfPath)
                                                          .bizSn(recom.getSerialNumber())
                                                          .createdAt(recom.getCreatedAt())
                                                          .patientName(recomInfo.getPatientName())
                                                          .patientGender(recomInfo.getPatientGender())
                                                          .patientAge(recomInfo.getPatientAge() + recomInfo.getPatientAgeUnit())
                                                          .uniqueId(uniqueId)
            .requestFrom(RecomSignParamBO.REQUEST_FROM_SYSTEM)
                                                          .pin(signPwd)
                                                          .build();
        try {
            esignFeignClient.signPh(recomPreSignVO);
        } catch (BusinessException e) {
            if (e.getCode() == ExceptionCodes.ESIGN_SIGN_PWD_ERR) {
                LOGGER.warn("处方审核-药师电子签名-签署密码错误 recomId:{}, msg:{}", recomId, e.getMessage());
                throw e;
            }
            LOGGER.warn("处方审核-药师电子签名异常 recomId:{}, msg:{}", recomId, e.getMessage());
            throw new BusinessException(ExceptionCodes.RECOM_CMS_AUDIT_SIGN_FAILED, e.getMessage());
        }
    }

    private String getDoctorSignFile(Long recomId) throws BusinessException {
        // 查询医师签名pdf文件
        RecomPrescription recomPrescription = recomCreaterService
                .getByRecomIdAndType(recomId, RecomPrescription.TYPE_DOCTOR_SIGN);
        if (recomPrescription == null) {
            LOGGER.warn("医师签名文件不存在，无法完成药师签名 recomId:{}", recomId);
            throw new BusinessException(ExceptionCodes.ESIGN_DOWNLOAD_FILE_FAILED, "医师签名文件不存在，无法完成药师签名");
        }
        String basePath = ConfigUtil.getString("sys.static.resources.base.path");
        return basePath + recomPrescription.getPrescriptionPhotoUrl();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void assignAuditPharmacis() throws BusinessException {
        // 查询未失效待审核处方
        List<MedicationRecom> recoms = medicationRecomRepository.getPendingRecom();
        if (CollectionUtils.isEmpty(recoms)) {
            LOGGER.info("[recom] 未查询到未失效待审核处方!");
            return;
        }
        List<Long> recomIds = recoms.stream().map(recom -> recom.getId()).collect(Collectors.toList());
        LOGGER.info("[recom] 处方重新分配药师定时查询未失效待审核处方： recomIds={}", recomIds);
        // 查询未分配药师处方
        List<RecomAuditLog> unallocateds = recomAuditLogRepository
                .findByStatusAndPharmacistIdAndRecomIdIn(RecomAuditLog.AUDIT_STATUS_PENDING, 0L,
                                                         recomIds);
        this.updateAuditPharmacist(unallocateds, false);

        // 查询超时处方列表
        Date changedAt = DateUtil.addMinutes(new Date(), -RECOM_AUDIT_TIMEOUT_MINUTE);
        List<RecomAuditLog> timeoutList =
                recomAuditLogRepository
                        .findByStatusAndPharmacistIdGreaterThanAndChangedAtBeforeAndRecomIdIn(RecomAuditLog.AUDIT_STATUS_PENDING,
                                                                                              0L,
                                                                                              changedAt, recomIds);
        this.updateAuditPharmacist(timeoutList, true);
    }

    @Override
    public void summaryPendingRecom() {
        List<SysAdminInfo> list = sysAdminInfoService.findAll();
        if (list.size() > 0) {
            long count = recomAuditLogRepository.countByStatus(RecomAuditLog.AUDIT_STATUS_PENDING);
            Template template = Template.RECOM_PENDING_NO;
            if (count > 0) {
                template = Template.RECOM_PENDING_SUMMARY;
            }
            for (SysAdminInfo s : list) {
                SMSUtil.sendSMS(s.getPhone(), template, count);
            }
        }
    }

    private void updateAuditPharmacist(List<RecomAuditLog> auditLogs, boolean reAssign) throws BusinessException {
        if (auditLogs.size() > 0) {
            for (int i = 0; i < auditLogs.size(); i++) {
                List<PharmacistVO> pharmacistVOS = pharmacistFeignClient.getAuditPharmacist(auditLogs.size());
                if (CollectionUtils.isNotEmpty(pharmacistVOS)) {
                    RecomAuditLog recomAuditLog = auditLogs.get(i);
                    // 如果不自动审核标识存在，那么就跳出这次循环
                    boolean existsKey = RedisUtil.keyOps().existsKey(CommonConstant.NOT_AUTO_ASSIGN_RECOM + recomAuditLog.getRecomId());
                    if (existsKey) {
                        continue;
                    }
                    //新处方随机分配药师，旧处方不能分配给和上次一样的药师，只有一个药师的话那就只能分配给这个药师
                    int randomInt = RandomUtil.randomInt(0, pharmacistVOS.size());
                    PharmacistVO pharmacist = pharmacistVOS.get(randomInt);

                    if (reAssign) {
                        //超时处方重新分配，不能再分给同样的药师
                        if (pharmacistVOS.size() > 1) {
                            pharmacistVOS = pharmacistVOS.stream().filter(p -> !p.getId().equals(recomAuditLog.getPharmacistId())).collect(Collectors.toList());
                            pharmacist = pharmacistVOS.get(RandomUtil.randomInt(0, pharmacistVOS.size()));
                            LOGGER.info(" 药师5分钟未审核 处方自动分配药师  recomId={}, lastPhId={}, nowPharmacistId={}", recomAuditLog.getRecomId(), recomAuditLog.getPharmacistId(), pharmacist.getId());
                        }
                    }
                    LOGGER.info(" 处方自动分配药师  recomId={}, nowPharmacistId={}", recomAuditLog.getRecomId(), pharmacist.getId());
                    try {
                        this.reassign(recomAuditLog, pharmacist, reAssign);
                    } catch (Exception e) {
                        LOGGER.error("处方审核重分配异常 recomId:{}, recomSn:{}", recomAuditLog.getRecomId(), recomAuditLog.getSerialNumber());
                    }
                }
            }
        }
    }

    @Override
    public void updateExpired() {
        //筛选超时未审核处方并更新为已失效
        List<RecomAuditLog> recoms = recomAuditLogRepository.getExpiredRecom();
        recoms.forEach(s -> {
            s.setStatus(RecomAuditLog.AUDIT_STATUS_EXPIRED);
            s.setChangedAt(new Date());
            try {
                recomService.saveCrmRecomConfirm(s.getRecomId(), s.getPharmacistId(), s.getPharmacistName(), System.currentTimeMillis(),
                                                 DrMedicationRecomInfo.CHECKING_STATUS_EXPIRED, DrMedicationRecomInfo.CHECKING_EXPIRED_DESC);
            } catch (BusinessException e) {
                LOGGER.error("处方失效消息发送失败：recomId={}", s.getRecomId());
            }
        });
        recomAuditLogRepository.update(recoms);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void reassign(RecomAuditLog recomAuditLog, PharmacistVO pharmacistVO, boolean reAssign) {
        LOGGER.info("处方重新分配！");
        // 校验处方是否正在被审核
        boolean inAudit = RedisUtil.keyOps().existsKey(RECOM_PHARMACIST_AUDIT_LOCK_KEY + recomAuditLog.getRecomId());
        if (inAudit) {
            LOGGER
                    .warn("处方正在被审核,调过处方重分配 recomId:{}, recomSn:{}", recomAuditLog.getRecomId(), recomAuditLog.getSerialNumber());
            return;
        }

        recomAuditLog.setPharmacistId(pharmacistVO.getId());
        recomAuditLog.setPharmacistName(pharmacistVO.getName());
        recomAuditLog.setChangedAt(new Date());
        recomAuditLog.setChangedBy("auto assign audit");
        recomAuditLogRepository.update(recomAuditLog);

        // 分配操作日志
        if (reAssign) {
            recomAuditOperationLogService
                    .addLog(recomAuditLog.getRecomId(), "系统", RecomAuditOperationLog.TYPE_REDISTRIBUTION);
            // 发送审核通知
            this.sendAuditNotice(recomAuditLog.getPharmacistId(), recomAuditLog.getSerialNumber(),
                                 RecomAuditOperationLog.TYPE_REDISTRIBUTION);

        }
        recomAuditOperationLogService
                .addLog(recomAuditLog.getRecomId(), "系统", RecomAuditOperationLog.TYPE_DISTRIBUTION, pharmacistVO.getName());
        // 发送审核通知
        this.sendAuditNotice(recomAuditLog.getPharmacistId(), recomAuditLog.getSerialNumber(),
                             RecomAuditOperationLog.TYPE_DISTRIBUTION);

        LOGGER.info("分配待审核处方 recomId:{}, 分配给药师:{}", recomAuditLog.getRecomId(), pharmacistVO.getName());
    }

    private void sendAuditNotice(Long pharmacistId, String recomSn, Integer type) {
        String pushUrl = ConfigUtil.getString("push.message.server");
        try {
            switch (type) {
                case RecomAuditOperationLog.TYPE_DISTRIBUTION:
                    LOGGER.info("给药师分配处方，发送分配处方系统通知！");
                    AppPushUtil
                            .sendPhPush(pushUrl, pharmacistId, String.format(PUSH_MSG_ASSIGN, recomSn), AppJumpProtocol.PH_HOME);
                    break;

                case RecomAuditOperationLog.TYPE_REDISTRIBUTION:
                    /*LOGGER.info("给药师分配处方，发送重新分配系统通知！");
                    AppPushUtil
                            .sendPhPush(pushUrl, pharmacistId, String.format(PUSH_MSG_REASSIGN, recomSn), AppJumpProtocol.PH_HOME);*/
                    break;

                default:
            }
        } catch (Exception e) {
            LOGGER.error("发送处方提醒PUSH异常 pharmacistId:{}, recomSn:{}", pharmacistId, recomSn);
        }

    }
}
